﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using DynamicLinqExtensions.Exceptions;

namespace DynamicLinqExtensions
{
    public static class DynamicWhereExtensions
    {
        public static IQueryable DynamicWhere(this IQueryable qry, string propertyName, dynamic criteria)
        {
            var propertyInfo = qry.GetPropertyInfo(propertyName);
            return qry.DynamicWhere(propertyInfo, (object)criteria);
        }

        public static IQueryable DynamicWhere(this IQueryable qry, PropertyInfo propertyInfo, dynamic criteria)
        {
            var propertyName = propertyInfo.Name;
            if (propertyInfo.PropertyType == typeof(Guid))
                return qry.Where(propertyName + ".Equals(@0)", (object)criteria);
            if (propertyInfo.PropertyType == typeof(Guid?))
                return qry.Where(propertyName + ".Value.Equals(@0)", (object)criteria);
            if (propertyInfo.PropertyType == typeof(int))
                return qry.Where(propertyInfo.Name + " = @0", int.Parse(((object)criteria).ToString()));
            return qry.Where(propertyName + " = @0", (object)criteria);
        }

        public static IQueryable DynamicWhereGreaterThanEqualTo(this IQueryable qry, PropertyInfo propertyInfo, dynamic criteria)
        {
            var propertyName = propertyInfo.Name;
            return qry.Where(string.Format("{0} >= @0", propertyName), (object)criteria);
        }
        public static IQueryable DynamicWhereGreaterThanEqualTo(this IQueryable qry, string propertyName, dynamic criteria)
        {
            var propertyInfo = qry.GetPropertyInfo(propertyName);
            return qry.DynamicWhereGreaterThanEqualTo(propertyInfo, (object) criteria);
        }

        public static IQueryable DynamicWhereLessThanEqualTo(this IQueryable qry, PropertyInfo propertyInfo, dynamic criteria)
        {
            var propertyName = propertyInfo.Name;
            return qry.Where(string.Format("{0} <= @0", propertyName), (object)criteria);
        }

        public static IQueryable DynamicWhereLessThanEqualTo(this IQueryable qry, string propertyName, dynamic criteria)
        {
            var propertyInfo = qry.GetPropertyInfo(propertyName);
            return qry.DynamicWhereLessThanEqualTo(propertyInfo, (object)criteria);
        }

        public static IQueryable DynamicWhereContains(this IQueryable qry, string propertyName, dynamic criteria)
        {
            var propertyInfo = qry.GetPropertyInfo(propertyName);
            return qry.DynamicWhereContains(propertyInfo, (object)criteria);
        }

        public static IQueryable DynamicWhereContains(this IQueryable qry, PropertyInfo propertyInfo, dynamic criteria)
        {
            var propertyName = propertyInfo.Name;
            return qry.Where(propertyName + ".Contains(@0)", (object) criteria);
        }
    }
}
